extends Area2D
class_name Display

enum State {
	EMPTY,
	PLAYER,
	NOISE,
	CRACKED,
}

@onready var parent = get_parent()

const speed : float = Globals.tile_size * 9
const jump_height : float = Globals.tile_size * 2.25
const jump_velocity : float = -sqrt(jump_height * 2 * Globals.gravity)

var display : Sprite2D
var noise : Sprite2D
var player : Sprite2D
var cracked_display : Sprite2D
var index : Label

@export var state : State : set = _set_state

static var box_count = 0
static var numbers_displayed = false

var current_box_index = 0

static func reset() -> void:
	box_count = 0
	numbers_displayed = false
	
func _set_state(new_state: State) -> void:
	state = new_state
	#workaround for onready setters
	if not is_inside_tree():
			await ready
	match new_state:
		State.EMPTY:
			display.visible = true
			noise.visible = false
			player.visible = false
			cracked_display.visible = false
			input_pickable = true
		State.PLAYER:
			display.visible = true
			noise.visible = false
			player.visible = true
			cracked_display.visible = false
			input_pickable = false
		State.NOISE:
			display.visible = true
			noise.visible = true
			player.visible = false
			cracked_display.visible = false
			input_pickable = false
		State.CRACKED:
			display.visible = true
			noise.visible = false
			player.visible = false
			cracked_display.visible = true
			input_pickable = false
func _ready() -> void:
	EventBus.player_moving_to_box.connect(move_to_box)
	display = $Sprites/Display
	noise = $Sprites/Noise
	player = $Sprites/Player
	cracked_display = $Sprites/CrackedDisplay
	index = $Sprites/Index
	
	if state == State.EMPTY or state == State.PLAYER:
		box_count += 1
		current_box_index = box_count
		index.text = str(current_box_index)

func _physics_process(_delta: float) -> void:
	if state != State.PLAYER:
		return
	if numbers_displayed:
		return
		
	if Input.is_action_just_pressed("player_jump") and parent.is_on_floor():
		parent.velocity.y = jump_velocity

	var direction := Input.get_axis("player_left", "player_right")
	if direction:
		parent.velocity.x = direction * speed
		parent.getting_force = true
	else:
		parent.getting_force = false

func move_to_box(box : Display) -> void:
	if state == State.PLAYER:
		if box.index.visible:
			box.index.visible = false
			index.visible = true
		state = State.EMPTY
		parent.velocity.x = 0
		box.state = State.PLAYER
		

func _on_input_event(_viewport, event: InputEvent, _shape) -> void:
	if event is InputEventMouseButton and event.pressed:
		EventBus.player_moving_to_box.emit(self)


func _on_area_entered(_area: Area2D) -> void:
	if state == State.EMPTY:
		state = State.NOISE
	elif state == State.PLAYER:
		state = State.NOISE
		await get_tree().create_timer(0.5).timeout
		SceneManager.change_to_scene("CURRENT")


func _on_area_exited(_area: Area2D) -> void:
	if state == State.NOISE:
		state = State.EMPTY

func _unhandled_key_input(event: InputEvent) -> void:
	event = event as InputEventKey
	if event.keycode == KEY_TAB and event.is_pressed() and !event.is_echo():
		if state == State.EMPTY:
			index.visible = !index.visible
		
	if OS.get_keycode_string(event.keycode) == str(current_box_index):
		if state == State.EMPTY:
			EventBus.player_moving_to_box.emit(self)
